/*
 * @Author: actor
 * @Date: 2023-11-13 15:43:57
 * @email: 395593455@qq.com
 * @LastEditors: actor
 * @LastEditTime: 2023-12-21 10:31:15
 * @FilePath: \i-hos-app\shared\emr\src\hooks\useHandleTable.ts
 * @Description: 电子病历表格操作
 */
import { reactive, toRefs } from 'vue'

// 接口约束
import { IPageConfigStore, IRowCol, ITableLog, IDomRect } from '../interface/page'
// store数据
import { usePageConfigStore } from '../store/pageConfig'

// 初始化表格操作记录的数据
let tableLog: ITableLog = reactive({
  startTD: null,
  endTD: null,
  totalCell: 0,
  tdRc: { startRowIndex: -1, startCellIndex: -1, endRowIndex: -1, endCellIndex: -1 },
  curResizeTD: {},
  curResizeTdNextSibling: {},
  resizeTd: false,
  resizeTr: false,
  resizeSelected: false,
  resizeMerge: false,
  curDom: null,
})

/**
 * 改变表格列表列宽和列高
 * 插入删除列行
 * 合并取消单元格
 */
export const useHandleTable = () => {
  // 解构 store的配置数据
  const configStore: IPageConfigStore = usePageConfigStore()
  const { activeEl, targetEl } = toRefs(configStore)

  // 初始化数据
  let resizeLine = document.querySelector('.table_resize_line') as HTMLElement

  /**
   * 获取单元格原始rowIndex和cellIndex
   */
  const getRC = (curTd: HTMLTableCellElement, totalCell: number) => {
    let _tr = curTd.parentNode as HTMLTableRowElement
    let _tbody = _tr.parentNode as HTMLTableElement

    //从第一行计算总的td数量 (最后一行也可以，其他行计算不准确)
    let _cellIndex: number = -1
    let _rowIndex: number = _tr.rowIndex

    if (_tr.cells.length == totalCell) {
      //没有被rowspan,colspan影响到的单元格
      _cellIndex = curTd.cellIndex
    } else {
      //被rowspan影响，往上找rowspan的行
      _cellIndex = curTd.cellIndex
      for (let i = _rowIndex - 1; i >= 0; i--) {
        for (let td of _tbody.rows[i].cells) {
          if (td.rowSpan > 1) {
            //curTd所在行下标和当前rowspan重合，并且处于curTd前（使用位置来定位）
            if ((td.parentNode as HTMLTableRowElement).rowIndex + td.rowSpan > _rowIndex && curTd.offsetLeft > td.offsetLeft) {
              _cellIndex += td.colSpan //加上次单元格colSpan
            }
          }
        }
      }

      //同一行中td的colspan合并计算
      for (let i = curTd.cellIndex - 1; i >= 0; i--) {
        _cellIndex += _tr.cells[i].colSpan - 1
      }
    }
    return JSON.stringify({
      startRowIndex: _rowIndex,
      startCellIndex: _cellIndex,
      endRowIndex: _rowIndex + curTd.rowSpan - 1,
      endCellIndex: _cellIndex + curTd.colSpan - 1,
    })
  }

  /**
   * 初始表格的原始rowIndex，cellIndex及跨行，跨列信息
   */
  const initTdRc = (table: HTMLTableElement) => {
    if (!!table) {
      let _firstRow: HTMLTableRowElement = table.rows[0] //用第一行计算总的td数量，其他行计算也可
      tableLog.totalCell = 0
      for (let td of _firstRow.cells) {
        tableLog.totalCell += td.colSpan
      }
      for (let i = 0; i < table.rows.length; i++) {
        for (let j = 0; j < table.rows[i].cells.length; j++) {
          table.rows[i].cells[j].setAttribute('rc', getRC(table.rows[i].cells[j], tableLog.totalCell))
        }
      }
    }
  }

  /**
   * 清除保存在store的数据
   */
  const clearConfigStore = (): void => {
    // 获取输入操作的节点
    configStore.$patch?.((state: IPageConfigStore) => {
      state.commonComponentActive = ''
      state.activeEl = ''
      state.targetEl = ''
      state.val = {}
    })
  }

  /**
   * 设置拖拽辅助线的位置
   */
  const addResizeLine = (): void => {
    // 设置渲染组件定位的位置
    resizeLine?.setAttribute(
      'style',
      `top:${tableLog.curResizeTD.t}px;
        left:${tableLog.curResizeTD.l}px;
        height: ${tableLog.resizeTd ? tableLog.curResizeTD.h : 1}px;
        width: ${tableLog.resizeTd ? 1 : tableLog.curResizeTD.w}px;
        display:block;
        cursor: ${tableLog.resizeTd ? 'col-resize' : 'row-resize'};`
    )
  }

  /**
   * 设置表格单元格选中状态
   */
  const addTdSelected = (ev?: any): void => {
    if (tableLog.resizeSelected) {
      let _tdRc = tableLog.tdRc as IRowCol
      for (let tr of activeEl?.value.rows) {
        for (let td of tr.cells) {
          let _rc = JSON.parse(td.getAttribute('rc') as string) as IRowCol
          //在范围内加上高亮样式
          if (
            _rc.startRowIndex >= _tdRc.startRowIndex &&
            _rc.endRowIndex <= _tdRc.endRowIndex &&
            _rc.startCellIndex >= _tdRc.startCellIndex &&
            _rc.endCellIndex <= _tdRc.endCellIndex
          ) {
            td.classList.add('selected')
          }
        }
      }
    }
  }

  /**
   *  合并处理文本
   */
  const getText = (): string => {
    let text: string[] = []
    for (let tr of activeEl?.value.rows) {
      // let hit = false;
      for (let td of tr.cells) {
        if (td.classList.contains('selected')) {
          text.push(td.innerHTML)
        }
      }
    }
    return text.join('')
  }

  /**
   * 取消表格单元格所有的选中状态
   */
  const removeTdSelected = (): void => {
    // 取消所有td的选中状态
    if (activeEl?.value != '') {
      for (let tr of activeEl?.value.rows) {
        for (let td of tr.cells) {
          td.classList.remove('selected')
        }
      }
    }
  }

  /**
   * 检查选中范围的rowspan和colspan
   */
  const checkTdRC = () => {
    let _rangeChange: Boolean = false
    for (let tr of activeEl?.value.rows) {
      for (let td of tr.cells) {
        let _rc = JSON.parse(td.getAttribute('rc') as string) as IRowCol
        let _tdRc = tableLog.tdRc as IRowCol
        let _rcLT: boolean =
          _rc.startRowIndex >= _tdRc.startRowIndex &&
          _rc.startRowIndex <= _tdRc.endRowIndex &&
          _rc.startCellIndex >= _tdRc.startCellIndex &&
          _rc.startCellIndex <= _tdRc.endCellIndex //左上
        let _rcLB: Boolean =
          _rc.endRowIndex >= _tdRc.startRowIndex &&
          _rc.endRowIndex <= _tdRc.endRowIndex &&
          _rc.startCellIndex >= _tdRc.startCellIndex &&
          _rc.startCellIndex <= _tdRc.endCellIndex //左下
        let _rcRT: Boolean =
          _rc.startRowIndex >= _tdRc.startRowIndex &&
          _rc.startRowIndex <= _tdRc.endRowIndex &&
          _rc.endCellIndex >= _tdRc.startCellIndex &&
          _rc.endCellIndex <= _tdRc.endCellIndex //右上
        let _rcRB: Boolean =
          _rc.endRowIndex >= _tdRc.startRowIndex &&
          _rc.endRowIndex <= _tdRc.endRowIndex &&
          _rc.endCellIndex >= _tdRc.startCellIndex &&
          _rc.endCellIndex <= _tdRc.endCellIndex //右下
        //判断单元格4个顶点是否在范围内
        if (
          _rcLT || //左上
          _rcLB || //左下
          _rcRT || //右上
          _rcRB //右下
        ) {
          let startRowIndex: number = Math.min.call(null, _tdRc.startRowIndex, _rc.startRowIndex)
          let endRowIndex: number = Math.max.call(null, _tdRc.endRowIndex, _rc.endRowIndex)
          let startCellIndex: number = Math.min.call(null, _tdRc.startCellIndex, _rc.startCellIndex)
          let endCellIndex: number = Math.max.call(null, _tdRc.endCellIndex, _rc.endCellIndex)
          if (_tdRc.startRowIndex > startRowIndex) {
            _tdRc.startRowIndex = startRowIndex
            _rangeChange = true
          }
          if (_tdRc.startCellIndex > startCellIndex) {
            _tdRc.startCellIndex = startCellIndex
            _rangeChange = true
          }
          if (_tdRc.endRowIndex < endRowIndex) {
            _tdRc.endRowIndex = endRowIndex
            _rangeChange = true
          }
          if (_tdRc.endCellIndex < endCellIndex) {
            _tdRc.endCellIndex = endCellIndex
            _rangeChange = true
          }
        }
      }
    }
    //范围有变化继续扩展
    if (_rangeChange) {
      checkTdRC()
    }
  }

  const getInsertCellIndex = (nextTr: any, offsetRight: any): number => {
    //找到拆分单元格时出现rowspan插入到新行中的单元格下标
    for (let td of nextTr.cells) {
      if (Math.abs(td.offsetLeft - offsetRight) < 2)
        //注意这里内容宽度会出现小数点，但是用offsetWidth取值是整数有舍入操作，所以要取差值
        return td.cellIndex
    }
    return 0 //找不到说明是在第一列合并的，返回0
  }

  /**
   * 鼠标按下操作
   */
  const tableMousedown = (ev: any): void => {
    // 当前元素
    let _target: any = ev.target
    if (_target.tagName == 'TD' || _target.tagName == 'TH') {
      // 1：鼠标左键;2：鼠标右键;
      if (ev.buttons == 1) {
        // 取消所有td的选中状态
        removeTdSelected()
        tableLog.resizeMerge = true
        // tableLog.resizeSelected = true
        tableLog.endTD = tableLog.startTD = _target
        tableLog.tdRc = JSON.parse(_target.getAttribute('rc') as string)
      }
      if (ev.buttons == 2 && !tableLog.resizeSelected) {
        tableLog.startTD = _target
        tableLog.tdRc = JSON.parse(_target.getAttribute('rc') as string)
      }

      // 鼠标按下移动
      if (_target.offsetWidth - ev.offsetX < 8 || _target.offsetHeight - ev.offsetY < 8) {
        tableLog.resizeSelected = false
        tableLog.resizeMerge = false
        if (!!activeEl?.value) activeEl?.value.classList.add('resizeTable')
        // 横向
        if (_target.offsetWidth - ev.offsetX < 8) {
          tableLog.resizeTd = true
          let _rect: DOMRect = _target.getBoundingClientRect()
          let _offsetParentRect: DOMRect = _target.offsetParent.getBoundingClientRect()
          let _nextSiblingReact: DOMRect = _target.nextSibling != null ? _target.nextSibling.getBoundingClientRect() : {}
          let _seat: any = {
            h: _offsetParentRect.height,
            t: _offsetParentRect.top,
            l: _rect.left + _rect.width,
          }
          // 保留当前列表单元格的数据
          tableLog.curResizeTD = Object.assign({}, JSON.parse(JSON.stringify(_rect)), _seat)
          // 保留当前列表单元格下一个兄弟的数据
          tableLog.curResizeTdNextSibling = JSON.parse(JSON.stringify(_nextSiblingReact))
          // 保留当前需要设置列的宽度的元素
          tableLog.curDom = _target.offsetParent.querySelector('colgroup').childNodes[_target.cellIndex]
          // 修改拖动辅助线样式
          addResizeLine()
        } else {
          tableLog.resizeTd = false
        }

        // 纵向
        if (_target.offsetHeight - ev.offsetY < 8) {
          tableLog.resizeTr = true
          let _rect: DOMRect = _target.parentNode.getBoundingClientRect()
          let _seat: any = {
            w: _rect.width,
            t: _rect.top + _rect.height,
            l: _rect.left,
          }
          // 保留当前列表单元格的数据
          tableLog.curResizeTD = Object.assign({}, JSON.parse(JSON.stringify(_rect)), _seat)
          // 保留当前需要设置列的高度的元素
          tableLog.curDom = _target.tagName == 'TD' ? _target.parentNode : _target
          // 修改拖动辅助线样式
          addResizeLine()
        } else {
          tableLog.resizeTr = false
        }
      }
    }
  }

  /**
   * 鼠标移动操作
   */
  const tablMousemove = (ev: any): void => {
    // 当前需要需要的元素
    let _target: any = ev.target

    if (_target.tagName == 'TD' || _target.tagName == 'TH') {
      // 更改鼠标样式
      if (_target.offsetWidth - ev.offsetX < 8) {
        _target.offsetParent.style.cursor = 'col-resize'
      } else if (_target.offsetHeight - ev.offsetY < 10) {
        _target.offsetParent.style.cursor = 'row-resize'
      } else {
        _target.offsetParent.style.cursor = ''
      }
    }

    // 移动鼠标设置辅助线位置样式，即列宽的位置
    if (tableLog.resizeTd) {
      let _curTD: IDomRect = tableLog.curResizeTD
      let _curTDNext: IDomRect = tableLog.curResizeTdNextSibling
      if (Object.values(_curTDNext).length > 0) {
        if (ev.pageX > _curTD.left && ev.pageX < _curTDNext.left + _curTDNext.width) {
          resizeLine.style.left = ev.pageX + 'px'
          _curTD.l = ev.pageX
        }
      } else {
        resizeLine.style.left = ev.pageX + 'px'
        _curTD.l = ev.pageX
      }
    }

    // 移动鼠标设置辅助线位置样式，即列高的位置
    if (tableLog.resizeTr) {
      resizeLine.style.top = ev.pageY + 'px'
      tableLog.curResizeTD.t = ev.pageY
    }

    // 移动鼠标，检查移动经过的单元格元素，设置表格单元格选中状态
    // 不在开始td和结束td移动时再触发检查
    if (
      _target.tagName == 'TD' &&
      ((tableLog.endTD != _target && tableLog.startTD != _target) || (tableLog.endTD && tableLog.startTD == _target)) &&
      tableLog.resizeMerge
    ) {
      tableLog.endTD = _target
      tableLog.resizeSelected = true
      removeTdSelected()

      if (tableLog.startTD != undefined && tableLog.endTD != undefined) {
        let startRC = JSON.parse(tableLog.startTD.getAttribute('rc') as string),
          endRC = JSON.parse(tableLog.endTD.getAttribute('rc') as string)

        //求2个单元格的开始rowIndex，结束rowIndex，开始cellIndex和结束cellIndex
        let startRowIndex = Math.min.call(null, startRC.startRowIndex, endRC.startRowIndex)
        let endRowIndex = Math.max.call(null, startRC.endRowIndex, endRC.endRowIndex)
        let startCellIndex = Math.min.call(null, startRC.startCellIndex, endRC.startCellIndex)
        let endCellIndex = Math.max.call(null, startRC.endCellIndex, endRC.endCellIndex)

        tableLog.tdRc = { startRowIndex, startCellIndex, endRowIndex, endCellIndex }
        checkTdRC()
        addTdSelected()
      }
    }

    // 松开鼠标
    document.onmouseup = (e) => {
      if (e.target && resizeLine && !!tableLog.curDom) {
        let _curTD: IDomRect = tableLog.curResizeTD
        // 设置列宽
        if (tableLog.resizeTd) {
          ;(tableLog.curDom as HTMLTableElement).style.width = _curTD.l - _curTD.left + 'px'
        }
        // 设置列高
        if (tableLog.resizeTr) {
          ;(tableLog.curDom as HTMLTableElement).style.height = _curTD.t - _curTD.top + 'px'
        }
        // 隐藏辅助线
        resizeLine.style.display = 'none'
        tableLog.resizeTr = false
        tableLog.resizeTd = false
        if (!!activeEl?.value) activeEl?.value.classList.remove('resizeTable')
      }
      // // 取消记录的状态
      // tableLog.resizeSelected = false
      tableLog.resizeMerge = false
    }
  }

  /**
   * 插入表格行列
   */
  const insertTable = (tp: string): void => {
    let _isRow: boolean = tp == 'insertRowBefore' || tp == 'insertRowAfter',
      _target: any = targetEl?.value, // 当前的td
      _trArr: any = activeEl?.value.querySelectorAll('tr') // 所有行

    /**
     * 判断插入行还是插入列
     */
    if (_isRow) {
      /**
       * 插入行
       */
      let _curTr: HTMLTableRowElement = _target.parentNode, // 当前行tr
        _rowIndex: number = _curTr.rowIndex, // 当前行在第几列
        _createTr: HTMLElement = document.createElement('tr'), // 创建一行
        _createCell: number = 0,
        _tdHtml: string = ''

      // // 判断是否在合并单元格的表格插入
      // if (_target.rowSpan > 1) {
      //   clearConfigStore()
      //   return
      // }

      // 计算要插入多少列(td)
      for (let td of _curTr.cells) {
        // 判断是向上插入还是下方插入以及是否有合并单元格的
        _createCell += tp == 'insertRowBefore' ? (td.colSpan > 1 ? td.colSpan : 1) : td.colSpan > 1 ? 0 : 1
      }

      // 计算当前插入行的范围是否在合并单元格范围
      for (let tr of _trArr) {
        for (let td of tr.cells) {
          let _rc: IRowCol = JSON.parse(td.getAttribute('rc') as string)
          if (!!td.getAttribute('rowspan')) {
            if (tp == 'insertRowBefore') {
              if (_rowIndex <= _rc.endRowIndex && _rowIndex > _rc.startRowIndex) {
                td.rowSpan += 1
              }
            } else {
              if (_rowIndex <= _rc.endRowIndex && _rowIndex >= _rc.startRowIndex) {
                td.rowSpan += 1
              }
            }
          }
        }
      }

      // 计算要插入多少td
      for (let j = 0; j < _createCell; j++) {
        _tdHtml += `<td></td>`
      }

      // 向指定的位置插入行列
      _createTr.innerHTML = _tdHtml
      _curTr.parentNode?.insertBefore(_createTr, tp == 'insertRowBefore' ? _curTr : _curTr.nextSibling)
    } else {
      /**
       * 插入列
       */
      let _curTdRc: IRowCol = JSON.parse(_target.getAttribute('rc') as string), // 当前td的行列范围
        _cellIndex: number = _curTdRc.startCellIndex // 当前列

      // 判断是否在合并单元格的表格插入
      // if (_target.colSpan > 1) {
      //   clearConfigStore()
      //   return
      // }

      // 获取列组并插入列
      let _targetColgroup: HTMLElement = activeEl?.value.querySelector('colgroup') // 当前列组
      let _targetCol: any = _targetColgroup.childNodes[_curTdRc.startCellIndex] //当前列
      let _createCol: HTMLElement = document.createElement('col') // 创建一个列
      _createCol.setAttribute('style', `width: 60px`) // 列的样式
      _targetColgroup.insertBefore(_createCol, tp == 'insertColBefore' ? _targetCol : _targetCol.nextSibling) // 插入列

      // 循环每一行，找到每一行对应的列执行操作
      for (let tr of _trArr) {
        for (let td of tr.cells) {
          let _rc = JSON.parse(td.getAttribute('rc') as string)
          if (
            !!td.getAttribute('colspan') &&
            td.colSpan > 1 &&
            _cellIndex <= _rc.endCellIndex &&
            _cellIndex >= _rc.startCellIndex
          ) {
            td.colSpan += 1
            break
          } else {
            if (_cellIndex == _rc.startCellIndex) {
              let _createTd: HTMLElement = document.createElement('td') // 创建一行td
              // _createTd.setAttribute('style', `height: 1.5em;border: 1px solid #000;`) // 列td的样式
              td.parentNode.insertBefore(_createTd, tp == 'insertColBefore' ? td : td.nextSibling)
              break
            }
          }
        }
      }
    }
    //重新初始化rc
    initTdRc(activeEl?.value)
    removeTdSelected()
    clearConfigStore()
  }

  /**
   * 删除表格，表格行列
   */
  const deleteTable = (tp: string): void => {
    if (tp == 'deleteTable') {
      /**
       *  删除整个表格
       */
      activeEl?.value.parentNode.removeChild(activeEl?.value)
    } else if (tp == 'deleteRow') {
      /**
       * 删除行
       */
      // 当前要删除的行
      let _row: number = JSON.parse(targetEl?.value.getAttribute('rc')).startRowIndex
      let _tabArr: any = []

      // 查找需要重新设置的td位置以及属性
      for (let j = 0; j < activeEl?.value.rows.length; j++) {
        let _tr: any = activeEl?.value.rows[j]
        for (let i = 0; i < _tr.cells.length; i++) {
          let _td = _tr.cells[i]
          let _rc: any = JSON.parse(_td.getAttribute('rc'))
          // 查找需要减少单元格和需要插入新的td
          if (_td.rowSpan > 1 && _rc.startRowIndex <= _row && _row <= _rc.endRowIndex) {
            if (_rc.startRowIndex == _row) {
              let _nextTdData: any = {
                _row: _td.rowSpan - 1,
                _col: _td.colSpan,
                _html: _td.innerHTML,
                _tr: _tr.nextSibling,
                _i: i,
              }
              _tabArr.push(_nextTdData)
            } else {
              _td.rowSpan -= 1
            }
          }
        }
      }
      // 在需要的位置设置插入新的td
      for (let curTr of _tabArr) {
        let _createTd: HTMLElement = document.createElement('td')
        _createTd.setAttribute('rowspan', String(curTr._row))
        _createTd.setAttribute('colspan', String(curTr._col))
        _createTd.innerHTML = curTr._html
        curTr._tr.insertBefore(_createTd, curTr._tr.children[curTr._i])
      }
      // 处理完成之后，删除当前行
      targetEl?.value.parentNode.remove()
    } else {
      /**
       * 删除列
       */
      let _col: number = targetEl?.value.cellIndex
      for (let tr of activeEl?.value.rows) {
        for (let td of tr.cells) {
          var _rc: IRowCol = JSON.parse(td.getAttribute('rc'))
          if (_rc.startCellIndex <= _col && _col <= _rc.endCellIndex) {
            if (_rc.startCellIndex == _rc.endCellIndex) {
              //只有一个，删掉
              td.parentNode.removeChild(td)
            } else {
              td.colSpan -= 1
            }
            break //后续单元格不需要再遍历在，直接下一行
          }
        }
      }
      let _colgroup: any = activeEl?.value.firstChild.children
      for (let i = 0; i <= _colgroup.length; i++) {
        if (i == _col) {
          _colgroup[i].parentNode.removeChild(_colgroup[i])
          break
        }
      }
    }
    initTdRc(activeEl?.value) //重新初始化rc
    removeTdSelected()
    clearConfigStore()
  }

  /**
   *  合并或取消合并表格
   */
  const mergeTable = (tp: string): void => {
    // 合并选中区域的单元格
    if (
      tableLog.startTD &&
      tableLog.endTD &&
      tableLog.startTD != tableLog.endTD &&
      Object.values(tableLog.tdRc as IRowCol).length > 0 &&
      tp == 'mergeCell'
    ) {
      let _tds: any = Array.from(activeEl?.value.querySelectorAll('td.selected')),
        _firstTD: HTMLTableRowElement = _tds[0] as HTMLTableRowElement,
        _html: string = getText()

      for (let i = 1; i < _tds.length; i++) {
        ;(_tds[i] as any).parentNode.removeChild(_tds[i])
      }

      // 文本处理
      _firstTD.innerHTML = _html

      let _tdRc = tableLog.tdRc as IRowCol
      //更新合并的第一个单元格的缓存rc数据为所跨列和行
      _firstTD.setAttribute('colspan', String(_tdRc.endCellIndex - _tdRc.startCellIndex + 1))
      _firstTD.setAttribute('rowspan', String(_tdRc.endRowIndex - _tdRc.startRowIndex + 1))
      _firstTD.setAttribute('rc', JSON.stringify(_tdRc))
      // 取消记录的状态
      tableLog.resizeSelected = false
    }

    // 向右或者向下合并
    if (tableLog.startTD && Object.values(tableLog.tdRc as IRowCol).length > 0) {
      let _tdRc = tableLog.tdRc as IRowCol

      if (tp == 'mergeRight') {
        // 向右合并
        let _nextTD = tableLog.startTD.nextSibling as HTMLTableRowElement
        if (_nextTD != null) {
          let _nextTdRc: IRowCol = JSON.parse(_nextTD.getAttribute('rc') as string)
          if (
            _tdRc.startRowIndex == _tdRc.endRowIndex &&
            _nextTdRc.startRowIndex == _nextTdRc.endRowIndex &&
            _tdRc.startRowIndex == _nextTdRc.startRowIndex &&
            _nextTdRc.startCellIndex - _tdRc.startCellIndex >= 1 &&
            _nextTdRc.endCellIndex - _tdRc.endCellIndex == 1
          ) {
            let startTdColspan: number = Number(tableLog.startTD.getAttribute('colspan') as string),
              nextTdColspan: number = Number(_nextTD.getAttribute('colspan') as string),
              colspan = !!nextTdColspan ? startTdColspan + nextTdColspan : !!startTdColspan ? ++startTdColspan : 2
            // 删除下一个，进行向右合并
            tableLog.startTD.parentNode?.removeChild(_nextTD)
            tableLog.startTD.innerHTML += _nextTD.innerHTML
            tableLog.startTD.setAttribute('rowspan', '1')
            tableLog.startTD.setAttribute('colspan', String(colspan))
          }
        }
      } else if (tp == 'mergeDown') {
        // 向下合并
        let _nextTDArr: any = activeEl?.value.querySelectorAll('tr')[_tdRc.endRowIndex + 1].querySelectorAll('td')
        let _nextTD: HTMLTableRowElement | null = null
        // 查找下一行对应的td
        for (let td of _nextTDArr) {
          let _curTdRc = JSON.parse(td.getAttribute('rc') as string)
          if (_curTdRc.startCellIndex == _tdRc.startCellIndex) {
            _nextTD = td
          }
        }
        if (_nextTD != null) {
          let _nextTdRc: IRowCol = JSON.parse(_nextTD.getAttribute('rc') as string)
          if (
            _tdRc.startCellIndex == _tdRc.endCellIndex &&
            _nextTdRc.startCellIndex == _nextTdRc.endCellIndex &&
            _tdRc.startCellIndex == _nextTdRc.startCellIndex &&
            _nextTdRc.startRowIndex - _tdRc.startRowIndex >= 1 &&
            _nextTdRc.endRowIndex - _tdRc.endRowIndex == 1
          ) {
            let startTdRowspan: number = Number(tableLog.startTD.getAttribute('rowspan')),
              nextTdRowspan: number = Number(_nextTD.getAttribute('rowspan')),
              rowspan = !!nextTdRowspan ? startTdRowspan + nextTdRowspan : !!startTdRowspan ? ++startTdRowspan : 2
            // 删除下一个，进行向下合并
            tableLog.startTD.innerHTML += _nextTD.innerHTML
            _nextTD.parentNode?.removeChild(_nextTD)
            tableLog.startTD.setAttribute('colspan', '1')
            tableLog.startTD.setAttribute('rowspan', String(rowspan))
          }
        }
      }

      //重新初始化rc
      initTdRc(activeEl?.value)
      tableLog.tdRc = tableLog.startTD = tableLog.endTD = null
    }
    removeTdSelected()
    clearConfigStore()
  }

  /**
   * 取消合并单元格
   */
  const breakCells = (): void => {
    let _RC = tableLog.tdRc as IRowCol
    if (_RC) {
      if (_RC.startRowIndex == _RC.endRowIndex && _RC.startCellIndex == _RC.endCellIndex) {
        return
      }

      let _rows: any = Array.from(activeEl?.value.rows),
        _cells: any

      for (let tr of _rows) {
        _cells = Array.from(tr.cells) //拷贝到数组，而不是直接遍历tr.cells，cells会受cellspan，rowspan影响
        for (let td of _cells) {
          let _rc: IRowCol = JSON.parse(td.getAttribute('rc') as string)
          if (!_rc) continue //rowspan新增的单元格跳过
          //在范围内
          if (
            _rc.startRowIndex >= _RC.startRowIndex &&
            _rc.endRowIndex <= _RC.endRowIndex &&
            _rc.startCellIndex >= _RC.startCellIndex &&
            _rc.endCellIndex <= _RC.endCellIndex
          ) {
            let _colSpan: number = _rc.endCellIndex - _rc.startCellIndex
            if (_colSpan > 0) {
              //跨列
              for (let i = 0, j = _colSpan; i < j; i++) {
                tr.insertCell(td.cellIndex + 1) //这个是在后面插入，前面插入+1
              }
              td.colSpan = 1
            }

            let _rowSpan: number = _rc.endRowIndex - _rc.startRowIndex
            if (_rowSpan > 0) {
              //跨行
              for (let k = 1; k <= _rowSpan; k++) {
                let nextTr: HTMLTableRowElement = activeEl?.value.rows[_rc.startRowIndex + k]
                let cellIndex: number = getInsertCellIndex(nextTr, td.offsetLeft + td.offsetWidth)

                for (let i = 0; i < _colSpan + 1; i++) {
                  nextTr.insertCell(cellIndex)
                }
              }
              td.rowSpan = 1
            }
          }
        }
      }
    }
    removeTdSelected()
    //重新初始化rc
    initTdRc(activeEl?.value)
  }

  return {
    tablMousemove,
    tableMousedown,
    insertTable,
    mergeTable,
    breakCells,
    deleteTable,
    initTdRc,
  }
}
